package com.yanqu.road.server.gameplayer.module.activity.horserun;


import com.yanqu.road.dao.impl.activity.horserun.game.HorseRunUserBaseDataDaoImpl;
import com.yanqu.road.dao.impl.activity.horserun.game.HorseRunUserGamingDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.horserun.HorseRunSkillData;
import com.yanqu.road.entity.activity.horserun.HorseRunUserBaseData;
import com.yanqu.road.entity.activity.horserun.HorseRunUserGamingData;
import com.yanqu.road.entity.activity.horserun.condition.HorseRunUnionScoreConditionArg;
import com.yanqu.road.entity.activity.horserun.config.*;
import com.yanqu.road.entity.enums.activity.horserun.eHorseRunAttrEnum;
import com.yanqu.road.entity.enums.activity.horserun.eHorseRunEventState;
import com.yanqu.road.entity.enums.activity.horserun.eHorseRunEventType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.horserun.*;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.logic.activity.horserun.HorseRunConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.HorseRunProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.fund.ActivityFundModule;
import com.yanqu.road.server.gameplayer.module.activity.horserun.event.HorseRunBaseEvent;
import com.yanqu.road.server.gameplayer.module.activity.horserun.event.HorseRunDealEventArg;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.horserun.HorseRunMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class HorseRunActivityModule extends GeneralModule {

    public HorseRunActivityModule(GamePlayer player) {
        super(player);
    }

    private HorseRunUserBaseData userBaseData;

    private HorseRunUserGamingData userGamingData;

    @Override
    public boolean loadData() {
        HorseRunConfig config = HorseRunMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            userBaseData = new HorseRunUserBaseDataDaoImpl().getHorseRunUserBaseData(config.getActivityId(), getUserId());
            userGamingData = new HorseRunUserGamingDataDaoImpl().getHorseRunUserGamingData(config.getActivityId(),getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userBaseData != null) {
            if (userBaseData.isInsertOption()){
                new HorseRunUserBaseDataDaoImpl().add(userBaseData);
            }else if (userBaseData.isUpdateOption()){
                new HorseRunUserBaseDataDaoImpl().update(userBaseData);
            }
        }
        if (userGamingData != null) {
            if (userGamingData.isInsertOption()){
                new HorseRunUserGamingDataDaoImpl().add(userGamingData);
            }else if (userGamingData.isUpdateOption()){
                new HorseRunUserGamingDataDaoImpl().update(userGamingData);
            }
        }

        return true;
    }

    public void init() {
        syncConfig();
        checkUserData();
        syncUserGamingData();
        syncUserBaseData();
        uploadHorseDataToCross();
        //向跨服拿东西
        updateUnionCondition();
    }

    @Override
    public void afterLogin() {
        init();
        if (HorseRunMgr.getConfig() != null) {
            HorseRunConfig config = HorseRunMgr.getConfig();
            if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
                return;
            }
            if (userBaseData == null){
                return;
            }
            if (userBaseData.getHorseAppearance() == 0){
                return;
            }

            int groupId = GameUnionActivityGroupMgr.getGroupId(config.getActivityId(), getUserId());
            if (groupId != UnionActivityGroupHelper.NO_GROUP_ID){
                UserMgr.syncUserBaseInfoToActivityCross(getUserId(),config.getActivityId(),groupId);
            }
        }
    }

    /**
     * 同步玩家游戏内数据
     */
    public void syncUserGamingData() {
        HorseRunProto.HorseRunGamingUserData.Builder gamingUserDataMsg = getGamingUserDataMsg(true);
        if (gamingUserDataMsg != null) {
            HorseRunProto.HorseRunUserGamingDataSyncMsg.Builder builder = HorseRunProto.HorseRunUserGamingDataSyncMsg.newBuilder();
            builder.setGamingData(gamingUserDataMsg);
            player.sendPacket(ClientProtocol.U_HORSE_RUN_SYNC_USER_GAMING_DATA, builder);
        }
    }

    /**
     * 同步玩家基础数据
     */
    public void syncUserBaseData() {
        HorseRunProto.HorseRunBaseUserData.Builder baseUserDataMsg = getBaseUserDataMsg();
        if (baseUserDataMsg != null) {
            HorseRunProto.HorseRunUserBaseDataSyncMsg.Builder builder = HorseRunProto.HorseRunUserBaseDataSyncMsg.newBuilder();
            builder.setBaseUserData(baseUserDataMsg);
            player.sendPacket(ClientProtocol.U_HORSE_RUN_SYNC_USER_BASE_DATA, builder);
        }
    }

    /**
     * 同步配置
     */
    public void syncConfig() {
        HorseRunProto.HorseRunConfig.Builder configMsg = HorseRunMgr.getConfigMsg(player.getLanguage());
        if (configMsg != null) {
            HorseRunProto.HorseRunSyncConfigMsg.Builder builder = HorseRunProto.HorseRunSyncConfigMsg.newBuilder();
            builder.setConfig(configMsg);
            player.sendPacket(ClientProtocol.U_HORSE_RUN_SYNC_CONFIG, builder);
        }
    }

    /**
     * 检测玩家数据是否生成
     */
    public void checkUserData() {

        if (HorseRunMgr.getConfig() == null) {
            return;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }
        initUserBaseData(activityInfo.getActivityId());
        initUserGamingData(activityInfo.getActivityId());
    }

    /**
     * 初始化玩家活动总数据
     * @param activityId
     */

    public synchronized void initUserBaseData(int activityId) {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return;
        }
        if (userBaseData != null) {
            if (userBaseData.getActivityId() == activityId) {
                return;
            }
        }
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, getUserId());
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return;
        }
        UnionActivityGroupUnion groupUnion = GameUnionActivityGroupMgr.getUnionData(activityId, getUserId());
        if (groupUnion == null) {
            return;
        }
        HorseRunUserBaseData baseData = new HorseRunUserBaseData();
        baseData.setActivityId(activityId);
        baseData.setUserId(player.getUserId());
        baseData.setHorseAppearance(0);         //本体外观 0 1 2 3 没选是0
        Map<Integer, Integer> initAttrLevelMap = HorseRunMgr.getInitAttrLevelMap();
        if (initAttrLevelMap == null || initAttrLevelMap.size() != 3) {
            log.error("小马快跑获取初始属性错误 活动id{}", activityId);
            return;
        }
        Map<Integer, Integer> initExtAttrMap = HorseRunMgr.getInitExtAttrMap();
        if (initExtAttrMap == null || initExtAttrMap.size() != 3) {
            log.error("小马快跑获取初始属性错误 活动id{}", activityId);
            return;
        }
        baseData.setExtAttr(initExtAttrMap);


        baseData.setPointAttrLevel(initAttrLevelMap);
        //用等级和技能加点算出基础数值 不带技能
        Map<Integer, Integer> baseAttrMap = HorseRunMgr.getBaseAttrMap(initAttrLevelMap, 1,initExtAttrMap);

        Map<Integer, Integer> totalAttrMap = HorseRunMgr.calTotalAttr(baseAttrMap, new ArrayList<>());
        baseData.setTotalAttrMap(totalAttrMap);
        baseData.setActivityGrade(HorseRunMgr.getGradeByAttr(totalAttrMap));


        baseData.setEquip(HorseRunMgr.getInitEquipMap());
        baseData.setSkill(new ConcurrentHashMap<>());
        baseData.setHasOpenGameTime(0);
        baseData.setAttrPoint(0);
        baseData.setHorseLevel(1);
        baseData.setHorseExp(0);
        baseData.setHasUnlockEquip(HorseRunMgr.getInitUnlockEquip());
        baseData.setCanPlay(0);
        baseData.setLockUnionId("");
        baseData.setTurnTableRemain(0);
        baseData.setBigLuckyTime(0);
        baseData.setRefreshAttrTime(0);

        baseData.setInsertOption();
        userBaseData = baseData;
    }

    /**
     * 初始化玩家游戏内数据
     * @param activityId
     */
    public synchronized void initUserGamingData(int activityId) {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return;
        }
        if (userGamingData != null) {
            if (userGamingData.getActivityId() == activityId) {
                return;
            }
        }
        HorseRunConfig config = HorseRunMgr.getConfig();
        if (config == null) {
            return;
        }
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, getUserId());
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return;
        }
        UnionActivityGroupUnion groupUnion = GameUnionActivityGroupMgr.getUnionData(activityId, getUserId());
        if (groupUnion == null) {
            return;
        }

        HorseRunUserGamingData tempGamingData = new HorseRunUserGamingData();
        tempGamingData.setActivityId(activityId);
        tempGamingData.setUserId(player.getUserId());
        tempGamingData.setProcessId(-1);
        tempGamingData.setStageId(0);
        tempGamingData.setEventId(0);
        tempGamingData.setGamingBaseAttr(new ConcurrentHashMap<>());
        tempGamingData.setEventTypeTriggerTimes(new ConcurrentHashMap<>());
        tempGamingData.setGamingTotalAttr(new ConcurrentHashMap<>());
        tempGamingData.setSkill(new ArrayList<>());
        tempGamingData.setGamingGrade(0);
        tempGamingData.setEventMap(new ConcurrentHashMap<>());
        tempGamingData.setCardEventMap(new ConcurrentHashMap<>());
        tempGamingData.setNowConfident(config.getInitConfidence());
        tempGamingData.setMaxConfident(config.getInitConfidence());
        tempGamingData.setExpEventStage(new ArrayList<>());
        tempGamingData.setUnlockNewEquip(new ArrayList<>());
        tempGamingData.setInsertOption();

        userGamingData = tempGamingData;
    }

    /**
     * 结束咯
     */
    public void overResetGamingData() {
        if (userGamingData == null) {
            return;
        }
        HorseRunConfig config = HorseRunMgr.getConfig();

        synchronized (userGamingData) {
            userGamingData.setProcessId(-1);
            userGamingData.setStageId(0);
            userGamingData.setEventId(0);
            userGamingData.setGamingBaseAttr(new ConcurrentHashMap<>());
            userGamingData.setGamingTotalAttr(new ConcurrentHashMap<>());
            userGamingData.setSkill(new ArrayList<>());
            userGamingData.setGamingGrade(0);
            userGamingData.setEventMap(new ConcurrentHashMap<>());
            userGamingData.setCardEventMap(new ConcurrentHashMap<>());
            userGamingData.setNowConfident(config==null?3:config.getInitConfidence());
            userGamingData.setMaxConfident(config==null?3:config.getInitConfidence());
            userGamingData.setExpEventStage(new ArrayList<>());
            userGamingData.setEventTypeTriggerTimes(new ConcurrentHashMap<>());

            userGamingData.setSumExp(0);
            userGamingData.setBattleHorseId(0);
            userGamingData.setChooseOneEventAttrType(0);
            userGamingData.setRemainExploreTime(0);
            userGamingData.setOpenGameMultiple(0);
            userGamingData.setEventState(0);
            userGamingData.setUnlockNewEquip(new ArrayList<>());
        }
    }

     /**
     * 开始新的一局游戏 选择的道路 1 2 3
     */
    public int startNewGame(int activityId, int openGameMultiple,int chooseRoad) {
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getHorseAppearance()<=0){
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_CHOOSE_APPEARANCE;
        }
        if (userGamingData.getProcessId() >= 0) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_REPEAT_OPENING;
        }
        HorseRunConfig config = HorseRunMgr.getConfig();
        //开启多倍需要已用甘草
        int multiOpenNeedUsed = config.getMultiOpenNeedUsed(openGameMultiple);
        if (multiOpenNeedUsed < 0) {
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }

        if (chooseRoad != 1 && chooseRoad != 2 && chooseRoad!=3){
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }
        if (chooseRoad != 1){
            if (userBaseData.getHadUseItemNum() < config.getOpenDiffRoadNeedTimeTime()){
                return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
            }
        }

        if (userBaseData.getHadUseItemNum() < multiOpenNeedUsed) {
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }
        int costItem = config.getOpenAdventureItem();
        Property cost = new Property(costItem, openGameMultiple);

        if (!player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.HorseRun, eLogMoneyType.HorseRunOpenCost)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //象征性保险 更新下值
        recalculateActivityAttrAndGrade(false);

        boolean startSuccess = gameStart(config, openGameMultiple,chooseRoad);
        if (!startSuccess) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
        }
        //设置消耗的冒险干粮+1
        userBaseData.setHadUseItemNum(userBaseData.getHadUseItemNum() + openGameMultiple);
        //设置开启游戏次数+1
        userBaseData.setHasOpenGameTime(userBaseData.getHasOpenGameTime() + 1);

        HorseRunStartAdventureLog horseRunStartAdventureLog = new HorseRunStartAdventureLog(activityId,getUserId(),userBaseData.getHasOpenGameTime(),PropertyHelper.parsePropertyToString(cost),userBaseData.getActivityGrade(),userBaseData.getSkillList(),userBaseData.getTotalAttrMap(),chooseRoad);
        AutoLogMgr.add(horseRunStartAdventureLog);

        HorseRunProto.HorseRunOpenAdventureResp.Builder resp = HorseRunProto.HorseRunOpenAdventureResp.newBuilder();

        HorseRunBaseEvent eventByType = HorseRunMgr.getEventByType(eHorseRunEventType.startGame.getValue());
        if (eventByType != null) {
            HorseRunEventConfig startGameConfig = config.getStartGameConfig();
            if (startGameConfig != null) {
                HorseRunProto.EventResult.Builder meet = eventByType.meet(userGamingData, config, startGameConfig);
                if (meet != null) {
                    resp.setResult(meet);
                }
            }
        }

        recalculateGamingAttrAndGrade();
        resp.setRet(0);
        resp.setUserGamingData(getGamingUserDataMsg(false));
        resp.setBaseUserData(getBaseUserDataMsg());


        player.sendPacket(ClientProtocol.U_HORSE_RUN_OPEN_ADVENTURE_REQ, resp);


        // 下面日志
//        Map<Integer,Integer> logAttrChange = new HashMap<>();
//        if (!meet.getAttrAddList().isEmpty()){
//            for (HorseRunProto.AttrRiseResult msg:meet.getAttrAddList()){
//                logAttrChange.put(msg.getType(),msg.getValue());
//            }
//        }
//
//        String propAdd = "";
//        if (!meet.getGoodRewardList().isEmpty()){
//            Property property = new Property();
//            for (String reward:meet.getGoodRewardList()){
//                property.addProperty(PropertyHelper.parseStringToProperty(reward));
//            }
//            propAdd = PropertyHelper.parsePropertyToString(property);
//        }

//        HorseRunEventLog horseRunEventLog = new HorseRunEventLog(activityId,getUserId()
//                ,userBaseData.getHasOpenGameTime()
//                ,userGamingData.getOpenGameMultiple()
//                ,userGamingData.getProcessId()
//                ,userGamingData.getDay()
//                ,1
//                ,userGamingData.getGamingGrade()
//                ,userGamingData.getNowConfident()
//                ,eventConfig.getId()
//                ,0
//                ,logAttrChange
//                ,propAdd
//                ,meet.hasExpAdd()?meet.getExpAdd():0
//                ,userGamingData.getBigLuckyTime()
//                ,userGamingData.getTurnTableRemain()
//        );
//        AutoLogMgr.add(horseRunEventLog);
        return 0;

    }

    /**
     * 选择外观
     */
    public int chooseAppearance(int activityId, int appearance) {
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getHorseAppearance() > 0) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_CHOOSE_APPEARANCE;
        }
        HorseRunConfig config = HorseRunMgr.getConfig();

        int groupId = GameUnionActivityGroupMgr.getGroupId(config.getActivityId(), getUserId());
        if (groupId != UnionActivityGroupHelper.NO_GROUP_ID){
            UserMgr.syncUserBaseInfoToActivityCross(getUserId(),config.getActivityId(),groupId);
        }

        userBaseData.setHorseAppearance(appearance);

        recalculateActivityAttrAndGrade(true);

        HorseRunProto.HorseRunChooseHorseAppearanceResp.Builder builder = HorseRunProto.HorseRunChooseHorseAppearanceResp.newBuilder();
        builder.setRet(0);
        builder.setBaseData(getBaseUserDataMsg());
        player.sendPacket(ClientProtocol.U_HORSE_RUN_CHOOSE_APPEARANCE,builder);
        //上传跨服生成数据 重要
        uploadHorseDataToCross();
        return 0;

    }

    /**
     * 替换技能
     * @param activityId
     * @param skillPosition
     * @return
     */

    public int replaceSkill(int activityId, int skillPosition) {
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        Map<Integer, HorseRunSkillData> skill = userBaseData.getSkill();
        HorseRunSkillData skillData = skill.get(skillPosition);
        if (skillData == null) {
            return GameErrorCode.E_HORSE_RUN_SKILL_NO_EXIST;
        }
        if (skillData.getReplaceSkillId() == 0){
            return GameErrorCode.E_HORSE_RUN_SKILL_NO_EXIST;
        }
        int oldSkillId = skillData.getSkillId();
        skillData.setSkillId(skillData.getReplaceSkillId());
        skillData.setReplaceSkillId(0);
        recalculateActivityAttrAndGrade(true);

        HorseRunProto.HorseRunRefreshSkillReplaceResp.Builder builder = HorseRunProto.HorseRunRefreshSkillReplaceResp.newBuilder();
        builder.setRet(0);
        HorseRunProto.HorseRunSkillDetailData.Builder skillBuild = HorseRunProto.HorseRunSkillDetailData.newBuilder();
        skillBuild.setPosition(skillData.getPosition());
        skillBuild.setSkillId(skillData.getSkillId());
        skillBuild.setReplaceSkillId(skillData.getReplaceSkillId());
        skillBuild.setItemRefreshTime(skillData.getItemTime());
        skillBuild.setIngotRefreshTime(skillData.getIngotTime());
        builder.setSkill(skillBuild);
        builder.setData(getBaseUserDataMsg());

        player.sendPacket(ClientProtocol.U_HORSE_RUN_SKILL_REPLACE,builder);
        //日志
        HorseRunSkillReplaceLog horseRunSkillReplaceLog = new HorseRunSkillReplaceLog(activityId, getUserId(), skillPosition, skillData.getSkillId(), oldSkillId, userBaseData.getActivityGrade());
        AutoLogMgr.add(horseRunSkillReplaceLog);
        return 0;
    }

    /**
     * 处理事件
     */
    public int dealEvent (int activityId, HorseRunProto.HorseRunDealEventArg argMsg){
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getHorseAppearance() <= 0) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_CHOOSE_APPEARANCE;
        }
        if (userGamingData.getProcessId() < 0) {
            return GameErrorCode.E_HORSE_RUN_GAME_NO_OPENING;
        }
        int eventId = userGamingData.getEventId();
        if (eventId == 0){
            return GameErrorCode.E_HORSE_RUN_EVENT_NO_EXIST;
        }

        if (userGamingData.getEventState() == eHorseRunEventState.done.getValue()) {
            return GameErrorCode.E_HORSE_RUN_EVENT_NO_EXIST;
        }

        HorseRunConfig config = HorseRunMgr.getConfig();
        HorseRunEventConfig eventConfig = config.getEventConfigById(eventId);
        if (eventConfig == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
        }
        HorseRunDealEventArg arg = new HorseRunDealEventArg(argMsg);

        HorseRunBaseEvent eventByType = HorseRunMgr.getEventByType(eventConfig.getType());
        if (eventByType == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
        }
        HorseRunProto.HorseRunDealEventResp.Builder builder = HorseRunProto.HorseRunDealEventResp.newBuilder();
        builder.setRet(0);

        HorseRunProto.EventResult.Builder deal = eventByType.deal(userGamingData, arg, config, eventConfig);
        if (!deal.hasError()){
            deal.setError(0);
        }
        if (!deal.getGoodRewardList().isEmpty()){
            for (String reward:deal.getGoodRewardList()){
                player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.HorseRun,eLogMoneyType.HorseRunAdventureGet);
            }
        }

        //更新游戏内的数据
        recalculateGamingAttrAndGrade();
        builder.setResult(deal);

        builder.setUserData(getGamingUserDataMsg(false));

        //游戏结束检测
        HorseRunProto.HorseRunGameOver.Builder gameOver = checkGameOver(userGamingData);
        if (gameOver != null) {
            builder.setOverData(gameOver);
        }

        player.sendPacket(ClientProtocol.U_HORSE_RUN_DEAL_EVENT, builder);


        // 下面日志
        Map<Integer,Integer> logAttrChange = new HashMap<>();
        if (!deal.getAttrAddList().isEmpty()){
            for (HorseRunProto.AttrRiseResult msg:deal.getAttrAddList()){
                logAttrChange.put(msg.getType(),msg.getValue());
            }
        }

        String propAdd = "";
        if (!deal.getGoodRewardList().isEmpty()){
            Property property = new Property();
            for (String reward:deal.getGoodRewardList()){
                property.addProperty(PropertyHelper.parseStringToProperty(reward));
            }
            propAdd = PropertyHelper.parsePropertyToString(property);
        }

        HorseRunEventLog horseRunEventLog = new HorseRunEventLog(activityId,getUserId()
                ,userBaseData.getHasOpenGameTime()
                ,userGamingData.getOpenGameMultiple()
                ,userGamingData.getProcessId()
                ,userGamingData.getDay()
                ,2
                ,userGamingData.getGamingGrade()
                ,userGamingData.getNowConfident()
                ,eventConfig.getId()
                ,deal.hasBattle()?deal.getBattle().getEnemyGrade():0
                ,logAttrChange
                ,propAdd
                ,deal.hasExpAdd()?deal.getExpAdd():0
                ,userBaseData.getBigLuckyTime()
                ,userBaseData.getTurnTableRemain()
        );
        AutoLogMgr.add(horseRunEventLog);
        return 0;
    }

    /**
     * 检测游戏是否结束
     * @param userGamingData
     * @return
     */

    public HorseRunProto.HorseRunGameOver.Builder checkGameOver(HorseRunUserGamingData userGamingData){
        if (userGamingData.getProcessId() >= 0 && userGamingData.getNowConfident() <= 0){
            HorseRunProto.HorseRunGameOver.Builder overBuild = HorseRunProto.HorseRunGameOver.newBuilder();
            int sumExp = userGamingData.getSumExp();
            overBuild.setAddExp(sumExp);
            HorseRunProto.HorseRunHorseLevelUpResult.Builder addExp = addExp(sumExp,2);
            if (addExp !=null){
                overBuild.setLevelUpResult(addExp);
            }
            //如果解锁了装备 发给客户端
            if (!userGamingData.getUnlockNewEquip().isEmpty()){
                overBuild.addAllUnlockEquip(userGamingData.getUnlockNewEquip());
            }

            //结束日志打一下
            HorseRunAdventureOverLog overLog = new HorseRunAdventureOverLog(userGamingData.getActivityId(),
                    userGamingData.getUserId(),
                    userBaseData.getHasOpenGameTime(),
                    userGamingData.getBackGround(),
                    userGamingData.getOpenGameMultiple(),
                    userGamingData.getDay(),
                    sumExp
                    );
            AutoLogMgr.add(overLog);

            gameOver();
            syncUserBaseData();


            return overBuild;
        }
        return null;
    }


    /**
     * 下一天
     */
    public int nextDay(int activityId) {
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getHorseAppearance() <= 0) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_CHOOSE_APPEARANCE;
        }
        if (userGamingData.getProcessId() < 0) {
            return GameErrorCode.E_HORSE_RUN_GAME_NO_OPENING;
        }

        if (userGamingData.getEventState() != eHorseRunEventState.done.getValue() && userGamingData.getEventId() != 0) {
            return GameErrorCode.E_HORSE_RUN_EVENT_NO_DONE;
        }

        HorseRunConfig config = HorseRunMgr.getConfig();

        if (userGamingData.getStageId() >= config.getStagePerProcess()) {
            userGamingData.setStageId(1);
            userGamingData.setProcessId(userGamingData.getProcessId()+1);
        }else {
            userGamingData.setStageId(userGamingData.getStageId()+1);
        }
        HorseRunEventConfig eventConfig = generalNewEvent(config);
        HorseRunBaseEvent eventByType = HorseRunMgr.getEventByType(eventConfig.getType());
        if (eventByType == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
        }
        if (userGamingData.getDay()> userBaseData.getHistoryMaxStage()){
            userBaseData.setHistoryMaxStage(userGamingData.getDay());
            //看看是不是有解锁新装备
            List<Integer> unlockEquip = checkUnlockEquip();
            //如果有的话 写道玩家数据里面
            if (unlockEquip != null && !unlockEquip.isEmpty()){
                userGamingData.getUnlockNewEquip().addAll(unlockEquip);
                userGamingData.setUpdateOption();
            }
        }


        HorseRunProto.EventResult.Builder meet = eventByType.meet(getUserGamingData(), config, eventConfig);
        if (!meet.hasError()){
            meet.setError(0);
        }
        //检测 如果是大吉事件加次数
        checkAddUserBigLuckyTime(getUserGamingData().getOpenGameMultiple(),config,eventConfig);
        //重算
        recalculateGamingAttrAndGrade();

        HorseRunProto.HorseRunNextDayResp.Builder builder = HorseRunProto.HorseRunNextDayResp.newBuilder();
        builder.setRet(0);

        builder.setUserData(getGamingUserDataMsg(false));

        builder.setResult(meet);

        player.sendPacket(ClientProtocol.U_HORSE_RUN_NEXT_DAY, builder);

        // 下面日志
        Map<Integer,Integer> logAttrChange = new HashMap<>();
        if (!meet.getAttrAddList().isEmpty()){
            for (HorseRunProto.AttrRiseResult msg:meet.getAttrAddList()){
                logAttrChange.put(msg.getType(),msg.getValue());
            }
        }

        String propAdd = "";
        if (!meet.getGoodRewardList().isEmpty()){
            Property property = new Property();
            for (String reward:meet.getGoodRewardList()){
                property.addProperty(PropertyHelper.parseStringToProperty(reward));
            }
            propAdd = PropertyHelper.parsePropertyToString(property);
        }

        HorseRunEventLog horseRunEventLog = new HorseRunEventLog(activityId,getUserId()
                ,userBaseData.getHasOpenGameTime()
                ,userGamingData.getOpenGameMultiple()
                ,userGamingData.getProcessId()
                ,userGamingData.getDay()
                ,1
                ,userGamingData.getGamingGrade()
                ,userGamingData.getNowConfident()
                ,eventConfig.getId()
                ,0
                ,logAttrChange
                ,propAdd
                ,meet.hasExpAdd()?meet.getExpAdd():0
                ,userBaseData.getBigLuckyTime()
                ,userBaseData.getTurnTableRemain()
                );
        AutoLogMgr.add(horseRunEventLog);
        return 0;
    }

    /**
     * 玩家大吉事件遇到次数大于n就转化为一次抽奖次数
     * @param time
     * @param config
     * @param eventConfig
     */

    public void checkAddUserBigLuckyTime( int time, HorseRunConfig config, HorseRunEventConfig eventConfig) {
        if (eventConfig==null ||eventConfig.getShow() != 3){
            return;
        }

        userBaseData.setBigLuckyTime(userBaseData.getBigLuckyTime()+time);
        int lotteryTime = userBaseData.getBigLuckyTime() / config.getBigLuckyLotteryNeedBigLuckyTime();
        if (lotteryTime > 0){
            userBaseData.setBigLuckyTime(userBaseData.getBigLuckyTime() - lotteryTime*config.getBigLuckyLotteryNeedBigLuckyTime());
            userBaseData.setTurnTableRemain(userBaseData.getTurnTableRemain()+1);
        }

    }

    /**
     * 生成下一天的事件
     */
    public HorseRunEventConfig generalNewEvent(HorseRunConfig config) {
        int stageId = userGamingData.getStageId();
        userGamingData.setEventState(eHorseRunEventState.noDeal.getValue());
        //最后一关是boss
        if (userGamingData.getStageId() == config.getStagePerProcess()) {
            HorseRunEventConfig bossEvent = config.getBossEvent();
            if (bossEvent == null) {
                log.error("horseRun bossEvent Config error activityId{}, userId {}", userGamingData.getActivityId(), userGamingData.getUserId());
                return null;
            }
            userGamingData.setEventId(bossEvent.getId());
            return bossEvent;
        }

        //如果是经验事件 还要随机出一个
        if (userGamingData.getExpEventStage().contains(stageId)) {
            HorseRunEventConfig eventConfig = config.randomExpEvent();
            if (eventConfig == null) {
                log.error("horseRun exp Config error activityId{}, userId {}", userGamingData.getActivityId(), userGamingData.getUserId());
                return null;
            }
            userGamingData.setEventId(eventConfig.getId());
            return eventConfig;
        }

        HorseRunEventConfig eventConfig = config.randomEvent(userGamingData);
        if (eventConfig == null) {
            log.error("horseRun simple event Config error activityId{}, userId {}", userGamingData.getActivityId(), userGamingData.getUserId());
            return null;
        }
        userGamingData.setEventId(eventConfig.getId());
        return eventConfig;
    }


    /**
     * 初始化一个阶段 因为要塞入经验事件
     */
    public void insertExpEvent() {
        List<Integer> randomExpEvent = HorseRunMgr.getRandomExpEvent();
        userGamingData.setExpEventStage(randomExpEvent);
    }


    /**
     * 游戏启动!
     */
    public boolean gameStart(HorseRunConfig config, int openGameMultiple,int road) {

        userGamingData.setProcessId(0);
        //策划说的 从0开始吧
        userGamingData.setStageId(0);

//        userGamingData.setEventId(config.getStage1Event());
//        //获取不带技能加成的数据
//        Map<Integer, Integer> baseAttrMap = HorseRunMgr.getBaseAttrMap(userBaseData.getPointAttrLevel(), userBaseData.getHorseLevel(),userBaseData.getExtAttr());
        //设置进玩家游戏数据 策划说里面不带技能了
        userGamingData.setGamingBaseAttr(new ConcurrentHashMap<>(userBaseData.getTotalAttrMap()));

        //总值
        userGamingData.setGamingTotalAttr(new ConcurrentHashMap<>(userBaseData.getTotalAttrMap()));
        //策划说里面不带技能了策划说里面不带技能了策划说里面不带技能了策划说里面不带技能了
        userGamingData.setSkill(new ArrayList<>());

        userGamingData.setGamingGrade(userBaseData.getActivityGrade());
        userGamingData.setMaxConfident(config.getInitConfidence());
        userGamingData.setNowConfident(config.getInitConfidence());
        userGamingData.setEventTypeTriggerTimes(new ConcurrentHashMap<>());

        userGamingData.setExpEventStage(new ArrayList<>());
        userGamingData.setOpenGameMultiple(openGameMultiple);
        userGamingData.setBackGround(road);
        userGamingData.setUnlockNewEquip(new ArrayList<>());

        insertExpEvent();
        return true;
    }

    /**
     * 游戏结束！
     */
    public boolean gameOver() {

        overResetGamingData();
        return true;
    }


    /**
     * 重新算游戏内数值
     */
    public void recalculateGamingAttrAndGrade() {
        if (userGamingData == null) {
            return;
        }
        Map<Integer, Integer> gamingBaseAttr = userGamingData.getGamingBaseAttr();
        Map<Integer, Integer> gamingTotalAttr = userGamingData.getGamingTotalAttr();
        Map<Integer, Integer> newTotalAttr = HorseRunMgr.calTotalAttr(gamingBaseAttr, userGamingData.getSkill());

        if (newTotalAttr.equals(gamingTotalAttr)) {
            return;
        }

        userGamingData.setGamingTotalAttr(newTotalAttr);
        userGamingData.setGamingGrade(HorseRunMgr.getGradeByAttr(newTotalAttr));
    }


    /**
     * 重新计算一下活动的游戏外数值
     */
    public void recalculateActivityAttrAndGrade(boolean forceUpdate) {
        if (userBaseData == null) {
            return;
        }
        //属性点加点等级
        Map<Integer, Integer> attrPointLevelMap = userBaseData.getPointAttrLevel();
        //额外属性
        Map<Integer, Integer> extAttr = userBaseData.getExtAttr();
        //之前的总属性
        Map<Integer, Integer> totalAttrMap = userBaseData.getTotalAttrMap();

        //用等级和属性加点算出基础数值 不带技能
        Map<Integer, Integer> baseAttrMap = HorseRunMgr.getBaseAttrMap(attrPointLevelMap, userBaseData.getHorseLevel(),userBaseData.getExtAttr());
        //加入技能
        Map<Integer, Integer> newTotalAttrMap = HorseRunMgr.calTotalAttr(baseAttrMap, userBaseData.getSkillList());
        //如果前后相等 而且不是强制更新就不管了
        if (totalAttrMap.equals(newTotalAttrMap) && !forceUpdate) {
            return;
        }
        //设置新的属性与值
        userBaseData.setTotalAttrMap(newTotalAttrMap);
        long newGrade = HorseRunMgr.getGradeByAttr(newTotalAttrMap);
        userBaseData.setActivityGrade(newGrade);

        uploadHorseDataToCross();       //上传跨服去

        //个人榜单
        player.notifyListener(eGamePlayerEventType.HorseRunPersonalGradeRank.getValue(), userBaseData);
        //成就榜单
        player.notifyListener(eGamePlayerEventType.HorseRunPersonalGradeAchievement.getValue(), newGrade);
    }

    //上传小马基础数据到跨服去
    public synchronized void uploadHorseDataToCross() {
        HorseRunConfig config = HorseRunMgr.getConfig();
        if (config == null) {
            return;
        }
        if (!ActivityMgr.activityInTime(config.getActivityInfo())){
            return;
        }

        if (userBaseData == null) {
            return;
        }
        if (userBaseData.getHorseAppearance() == 0){
            return;
        }

        HorseRunProto.HorseBriefData.Builder briefDataMsg = getBriefDataMsg();
        if (briefDataMsg == null) {
            return;
        }

        HorseRunProto.HorseRunUploadDataToCrossMsg.Builder builder = HorseRunProto.HorseRunUploadDataToCrossMsg.newBuilder();
        builder.setActivityId(config.getActivityId());
        builder.setUserId(getUserId());
        builder.setBriefData(briefDataMsg);

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_UPLOAD_BRIEF_HORSE_DATA, builder,config.getActivityId());

    }

    //转换简单小马数据
    public HorseRunProto.HorseBriefData.Builder getBriefDataMsg() {
        if (userBaseData == null) {
            return null;
        }
        HorseRunProto.HorseBriefData.Builder builder = HorseRunProto.HorseBriefData.newBuilder();
        builder.addAllHorseRunEquip(userBaseData.getEquipList());
        builder.setLevel(userBaseData.getHorseLevel());
        builder.addAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));
        builder.setGrade(userBaseData.getActivityGrade());
        builder.addAllSkill(userBaseData.getSkillList());
        builder.setAppearance(userBaseData.getHorseAppearance());

        builder.addExtAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addExtAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addExtAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));


        return builder;
    }

    /**
     * 活动内游戏外基础数据转消息
     */
    public HorseRunProto.HorseRunBaseUserData.Builder getBaseUserDataMsg() {
        if (userBaseData == null) {
            return null;
        }

        HorseRunProto.HorseRunBaseUserData.Builder builder = HorseRunProto.HorseRunBaseUserData.newBuilder();
        builder.setHorseAppearance(userBaseData.getHorseAppearance());
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addPointAttrLevel(userBaseData.getPointAttrLevel().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));
        builder.addTotalAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addTotalAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addTotalAttr(userBaseData.getTotalAttrMap().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));
        builder.setActivityGrade(userBaseData.getActivityGrade());
        builder.addAllHorseRunEquip(userBaseData.getEquipList());
        for (HorseRunSkillData skillData : userBaseData.getSkill().values()) {
            HorseRunProto.HorseRunSkillDetailData.Builder skillBuild = HorseRunProto.HorseRunSkillDetailData.newBuilder();
            skillBuild.setPosition(skillData.getPosition());
            skillBuild.setSkillId(skillData.getSkillId());
            skillBuild.setIngotRefreshTime(skillData.getIngotTime());
            skillBuild.setItemRefreshTime(skillData.getItemTime());

            skillBuild.setReplaceSkillId(skillData.getReplaceSkillId());
            builder.addSkill(skillBuild);
        }
        builder.setHadUseOpenItemNum(userBaseData.getHadUseItemNum());
        builder.setRemainAttrPointTimes(userBaseData.getAttrPoint());
        builder.setHorseLevel(userBaseData.getHorseLevel());
        builder.setHorseExp(userBaseData.getHorseExp());
        builder.setHistoryMaxStage(userBaseData.getHistoryMaxStage());
        builder.addAllHasEquip(userBaseData.getHasUnlockEquip());

        builder.setBigLuckyTimes(userBaseData.getBigLuckyTime());
        builder.setTurnAbleTimes(userBaseData.getTurnTableRemain());

        builder.addExtraAddAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addExtraAddAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addExtraAddAttr(userBaseData.getExtAttr().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));

        builder.setRefreshAttrLevelTime(userBaseData.getRefreshAttrTime());
        return builder;

    }


    /**
     * 游戏内数据转消息
     *
     * @param allLog
     * @return
     */
    public HorseRunProto.HorseRunGamingUserData.Builder getGamingUserDataMsg(boolean allLog) {
        if (userGamingData == null) {
            return null;
        }
        HorseRunProto.HorseRunGamingUserData.Builder builder = HorseRunProto.HorseRunGamingUserData.newBuilder();
        builder.setProcessId(userGamingData.getProcessId());
        builder.setStageId(userGamingData.getStageId());
        builder.setEventId(userGamingData.getEventId());
        builder.addGamingAttr(userGamingData.getGamingTotalAttr().getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
        builder.addGamingAttr(userGamingData.getGamingTotalAttr().getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
        builder.addGamingAttr(userGamingData.getGamingTotalAttr().getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));
        builder.setGamingGrade(userGamingData.getGamingGrade());
        if (allLog) {
            Map<Integer, List<List<Integer>>> eventMap = userGamingData.getEventMap();
            for (Map.Entry<Integer, List<List<Integer>>> entry : eventMap.entrySet()) {
                int day = entry.getKey();

                List<List<Integer>> value = entry.getValue();
                for (List<Integer> list : value) {
                    HorseRunProto.HorseRunEventLog.Builder logBuild = HorseRunProto.HorseRunEventLog.newBuilder();
                    logBuild.setDay(day);
                    logBuild.setEventId(list.get(0));
                    logBuild.setType(list.get(1));
                    if (list.size() > 2) {
                        List<Integer> integers = list.subList(2, list.size());
                        logBuild.addAllParam(integers);
                    }
                    builder.addEventLog(logBuild);
                }
            }
        }


        if (userGamingData.getCardEventMap() != null) {
            HorseRunProto.HorseRunCardEventCache.Builder cardBuild = HorseRunProto.HorseRunCardEventCache.newBuilder();
            if (!userGamingData.getCardEventMap().isEmpty()) {
                for (Map.Entry<Integer, Integer> entry : userGamingData.getCardEventMap().entrySet()) {
                    HorseRunProto.HorseRunCard.Builder cardPosition = HorseRunProto.HorseRunCard.newBuilder();
                    cardPosition.setPosition(entry.getKey());
                    cardPosition.setCard(entry.getValue());
                    cardBuild.addCard(cardPosition);
                }
            }
            builder.setCardEvent(cardBuild);
        }

        builder.setExploreEventRemain(userGamingData.getRemainExploreTime());
        builder.setAdventureUseItemNum(userGamingData.getOpenGameMultiple());
        builder.setAdventureBackGround(userGamingData.getBackGround());

        builder.setEventState(userGamingData.getEventState());
        builder.setConfident(userGamingData.getNowConfident());
        builder.setMaxConfident(userGamingData.getMaxConfident());
        builder.setExpGet(userGamingData.getSumExp());
        builder.setChooseOneEventAddType(userGamingData.getChooseOneEventAttrType());

        return builder;
    }


    /**
     * 玩家数据检测
     */
    public int userDataCheck(int activityId) {
        if (userBaseData == null || userBaseData.getActivityId() != activityId) {
            if (isInShowTime(activityId) != 0){
               return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
            }
            initUserBaseData(activityId);
            if (userBaseData == null || userBaseData.getActivityId() != activityId) {
                return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
            }
        }

        if (userGamingData == null || userGamingData.getActivityId() != activityId) {
            if (isInShowTime(activityId) != 0){
                return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
            }
            initUserGamingData(activityId);
            if (userGamingData == null || userGamingData.getActivityId() != activityId) {
                return GameErrorCode.E_HORSE_RUN_ACTIVITY_USER_DATA_ERROR;
            }
        }
        return 0;
    }


    /**
     * 基础操作检测
     */
    public int checkCanPlayingGame(int activityId) {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_UNLOCK;
        }

        if (HorseRunMgr.getConfig() == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        //如果玩家身上是不给玩的状态 就去拿一下他的group
        if (userBaseData == null ){
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        if ( userBaseData.getCanPlay() == 0){
            int groupId = GameUnionActivityGroupMgr.getGroupId(activityInfo.getActivityId(), getUserId());
            if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
                return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_JOIN_QUALIFICATION;
            }
            UnionActivityGroupUnion groupUnion = GameUnionActivityGroupMgr.getUnionData(activityInfo.getActivityId(), getUserId());
            if (groupUnion == null) {
                return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_LOCK_UNION;
            }else {
                userBaseData.setCanPlay(1);
                userBaseData.setLockUnionId(groupUnion.getUnionUid());
            }
        }
        //不在活动时间不给玩
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_IN_TIME;
        }
        if (activityInfo.getActivityId() != activityId) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_ID_ERROR;
        }


        return 0;
    }

    public HorseRunUserGamingData getUserGamingData() {
        return userGamingData;
    }

    public HorseRunUserBaseData getUserBaseData() {
        return userBaseData;
    }

    /**
     * 获取玩家游戏内数据
     */
    public int getUserGamingDataReq(int activityId,boolean allLog){
        if (HorseRunMgr.getConfig() == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        checkUserData();
        if (userBaseData == null || userBaseData.getActivityId() != activityId) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_UNLOCK;
        }
        HorseRunProto.HorseRunGetUserGamingDataResp.Builder builder = HorseRunProto.HorseRunGetUserGamingDataResp.newBuilder();
        builder.setRet(0);
        builder.setGamingData(getGamingUserDataMsg(allLog));
        player.sendPacket(ClientProtocol.U_HORSE_RUN_GET_USER_GAMING_DATA_REQ, builder);
        return 0;
    }


    /**
     * 获取玩家基础数据
     *
     * @param activityId
     * @return
     */

    public int getUserBaseDataReq(int activityId) {
        if (HorseRunMgr.getConfig() == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        checkUserData();
        if (userBaseData == null || userBaseData.getActivityId() != activityId) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_UNLOCK;
        }
        HorseRunProto.HorseRunGetUserBaseDataResp.Builder builder = HorseRunProto.HorseRunGetUserBaseDataResp.newBuilder();
        builder.setRet(0);
        builder.setBaseUserData(getBaseUserDataMsg());
        player.sendPacket(ClientProtocol.U_HORSE_RUN_GET_USER_BASE_DATA_REQ, builder);

        return 0;
    }

    /**
     * 小马快跑刷新技能 使用消耗类型 1道具 2元宝
     */
    public int refreshSkill(int activityId, int position,int costType) {

        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        HorseRunConfig config = HorseRunMgr.getConfig();

        Map<Integer, HorseRunSkillData> skillDataMap = userBaseData.getSkill();
        if (!skillDataMap.containsKey(position)) {
            return GameErrorCode.E_HORSE_RUN_SKILL_NO_EXIST;
        }
        HorseRunSkillData skillData = skillDataMap.get(position);
        if (skillData == null) {
            return GameErrorCode.E_HORSE_RUN_SKILL_NO_EXIST;
        }
        Property cost = new Property();
        if (costType == 1){
            int refreshEntryItemId = config.getRefreshEntryItem();
            if (refreshEntryItemId <= 0) {
                log.error("小马快跑刷新技能道具配置错误,activityId:{}",activityId);
                return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
            }

            int refreshItemNum = config.getRefreshItemNum(skillData.getItemTime());
            cost.addProperty(refreshEntryItemId, refreshItemNum);
        }else if (costType == 2){
            int refreshIngotNum = config.getRefreshIngotNum(skillData.getIngotTime());
            cost.addProperty(GameConfig.GAME_MONEY_INGOTS, refreshIngotNum);
        }
        else {
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }
        if (cost.isNothing()){
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }

        HorseRunSkillConfig randomSkill = config.getRandomSkill();
        if (randomSkill == null) {
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }

        if (!player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.HorseRun, eLogMoneyType.HorseRunRefreshSkillCost)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        int oldSkillId = skillData.getReplaceSkillId();

        if (costType == 1){
            skillData.setItemTime(skillData.getItemTime()+1);
        }else{
            skillData.setIngotTime(skillData.getIngotTime()+1);
        }

        skillData.setReplaceSkillId(randomSkill.getId());

        HorseRunProto.HorseRunRefreshSkillResp.Builder builder = HorseRunProto.HorseRunRefreshSkillResp.newBuilder();
        builder.setRet(0);

        HorseRunProto.HorseRunSkillDetailData.Builder skillBuild = HorseRunProto.HorseRunSkillDetailData.newBuilder();
        skillBuild.setSkillId(skillData.getSkillId());
        skillBuild.setReplaceSkillId(skillData.getReplaceSkillId());
        skillBuild.setIngotRefreshTime(skillData.getIngotTime());
        skillBuild.setItemRefreshTime(skillData.getItemTime());
        skillBuild.setPosition(skillData.getPosition());
        builder.setSkillData(skillBuild);

        builder.setData(getBaseUserDataMsg());

        userBaseData.setUpdateOption();

        player.sendPacket(ClientProtocol.U_HORSE_RUN_REFRESH_SKILL, builder);

        HorseRunSkillRefreshLog horseRunSkillRefreshLog = new HorseRunSkillRefreshLog(activityId, getUserId(), position, PropertyHelper.parsePropertyToString(cost), randomSkill.getId(), oldSkillId, 0,skillData.getIngotTime(),skillData.getItemTime());
        AutoLogMgr.add(horseRunSkillRefreshLog);

        return 0;
    }

    /**
     * 使用技能点升级技能
     *
     * @param activityId
     * @param addType
     * @return
     */

    public int usePointAddAttr(int activityId, int addType) {
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }
        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getAttrPoint() <= 0) {
            return GameErrorCode.E_HORSE_RUN_ATTR_POINT_NO_ENOUGH;
        }
        if (eHorseRunAttrEnum.forValue(addType) == null) {
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }

        //扣属性点
        userBaseData.setAttrPoint(userBaseData.getAttrPoint() - 1);
        userBaseData.addAttrLevel(addType, 1);
        //重新算分 上传
        recalculateActivityAttrAndGrade(false);

        //日志
        HorseRunAttrLevelAddLog horseRunAttrLevelAddLog = new HorseRunAttrLevelAddLog(activityId, getUserId(), addType, userBaseData.getAttrPoint(),
                1, userBaseData.getPointAttrLevel().getOrDefault(addType, 0), userBaseData.getActivityGrade());
        AutoLogMgr.add(horseRunAttrLevelAddLog);

        HorseRunProto.HorseRunUpgradeAttrPointResp.Builder builder = HorseRunProto.HorseRunUpgradeAttrPointResp.newBuilder();
        builder.setRet(0);
        builder.setData(getBaseUserDataMsg());

        player.sendPacket(ClientProtocol.U_HORSE_RUN_UPGRADE_ATTR, builder);
        return 0;
    }

    /**
     * 获得经验 跨服下来也会有 所以锁一下 类型1是商会 2是结束游戏 3是转盘
     *
     * @param exp
     * @return
     */

    public synchronized HorseRunProto.HorseRunHorseLevelUpResult.Builder addExp(long exp,int type) {

        long oldExp = userBaseData.getHorseExp();
        int oldLevel = userBaseData.getHorseLevel();
        Map<Integer, Integer> oldTotalAttrMap = new HashMap<>(userBaseData.getTotalAttrMap());

        int newAttrPointNum = 0;
        List<Integer> newSkill = new ArrayList<>();

        HorseRunConfig config = HorseRunMgr.getConfig();

        userBaseData.setHorseExp(userBaseData.getHorseExp() + exp);
        for (int i = 0; i < 1000; i++) { //保守循环
            int horseLevel = userBaseData.getHorseLevel();
            HorseRunLevelConfig levelConfig = config.getLevelConfigById(horseLevel);
            //当前等级配置
            if (levelConfig == null) {
                break;
            }
            //最高级了
            int needExp = levelConfig.getNeedExp();
            if (needExp <= 0) {
                break;
            }
            //经验不够升级
            if (userBaseData.getHorseExp() < needExp) {
                break;
            }
            HorseRunLevelConfig nextLevel = config.getLevelConfigById(horseLevel + 1);
            if (nextLevel == null) {
                break;
            }


            userBaseData.setHorseExp(userBaseData.getHorseExp() - needExp);
            userBaseData.setHorseLevel(horseLevel + 1);
            //每到n的倍数等级获得一个新的技能孔
            if (nextLevel.getGetSkill() == 1) {
                int newSkillId = addNewSkill();
                newSkill.add(newSkillId);
            }
            newAttrPointNum++;
        }

        HorseRunGetExpLog expLog = new HorseRunGetExpLog(userBaseData.getActivityId(),getUserId(),exp,type);
        AutoLogMgr.add(expLog);

        //如果升级了
        if (newAttrPointNum > 0) {

            userBaseData.setAttrPoint(userBaseData.getAttrPoint() + newAttrPointNum);

            HorseRunProto.HorseRunHorseLevelUpResult.Builder builder = HorseRunProto.HorseRunHorseLevelUpResult.newBuilder();
            builder.addOldAttr(oldTotalAttrMap.getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
            builder.addOldAttr(oldTotalAttrMap.getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
            builder.addOldAttr(oldTotalAttrMap.getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));

            builder.setOldLv(oldLevel);
            builder.setNewLv(userBaseData.getHorseLevel());

            recalculateActivityAttrAndGrade(true);

            Map<Integer, Integer> newMap = userBaseData.getTotalAttrMap();

            builder.addNewAttr(newMap.getOrDefault(eHorseRunAttrEnum.energy.getValue(), 0));
            builder.addNewAttr(newMap.getOrDefault(eHorseRunAttrEnum.artful.getValue(), 0));
            builder.addNewAttr(newMap.getOrDefault(eHorseRunAttrEnum.resistance.getValue(), 0));

            builder.addAllNewSkill(newSkill);
            builder.setData(getBaseUserDataMsg());
            return builder;
        }
        //日志
        Map<Integer, Integer> pointAttrLevel = userBaseData.getPointAttrLevel();
        HorseRunLeverUpLog horseRunLeverUpLog = new HorseRunLeverUpLog(config.getActivityId(), getUserId(), newAttrPointNum, userBaseData.getHorseLevel(), userBaseData.getActivityGrade(),
                pointAttrLevel.getOrDefault(1, 0),
                pointAttrLevel.getOrDefault(2, 0),
                pointAttrLevel.getOrDefault(3, 0),
                userBaseData.getSkill().size(),
                userBaseData.getAttrPoint()
        );
        AutoLogMgr.add(horseRunLeverUpLog);

        return null;
    }

    /**
     * 升级后添加新技能
     *
     * @return
     */

    public int addNewSkill() {
        HorseRunConfig config = HorseRunMgr.getConfig();

        int maxSkillPosition = 0;
        Map<Integer, HorseRunSkillData> skill = userBaseData.getSkill();
        for (HorseRunSkillData skillData : skill.values()) {
            if (skillData.getPosition() > maxSkillPosition) {
                maxSkillPosition = skillData.getPosition();
            }
        }
        HorseRunSkillData newSkill = new HorseRunSkillData();
        newSkill.setPosition(maxSkillPosition + 1);
        newSkill.setReplaceSkillId(0);
        newSkill.setSkillId(0);
        newSkill.setItemTime(0);
        newSkill.setIngotTime(0);

        skill.put(newSkill.getPosition(), newSkill);

        HorseRunSkillConfig randomSkill = config.getRandomSkill();
        if (randomSkill != null) {
            newSkill.setSkillId(randomSkill.getId());
        }

        return newSkill.getSkillId();
    }

    /**
     * 检测解锁装备
     */
    public List<Integer> checkUnlockEquip(){
        HorseRunConfig config = HorseRunMgr.getConfig();
        List<Integer> unlockEquip = new ArrayList<>();
        if (config == null){
            return unlockEquip;
        }
        if (userBaseData.getHasUnlockEquip() == null){
            userBaseData.setHasUnlockEquip(new ArrayList<>());
        }
        List<Integer> hasUnlockEquip = userBaseData.getHasUnlockEquip();
        //遍历所有装备
        for (HorseRunEquipConfig equipConfig:config.getEquipConfigs().values()){
            //如果包含这个 就检查下一个
            if (hasUnlockEquip.contains(equipConfig.getId())) {
                continue;
            }
            //非等级解锁的也不能解锁
            if (equipConfig.getLevel()<0){
                continue;
            }

            //如果等级大于需求 就+进去
            if (userBaseData.getHistoryMaxStage() >= equipConfig.getLevel()) {
                hasUnlockEquip.add(equipConfig.getId());
                unlockEquip.add(equipConfig.getId());
                userBaseData.setUpdateOption();
            }
        }
        return unlockEquip;
    }


    /**
     * 解锁装备 策划改成自动 此处不可达
     */
    public int unlockEquip(int activityId,int equipId){
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        HorseRunConfig config = HorseRunMgr.getConfig();
        if (userBaseData.getHasUnlockEquip() == null){
            userBaseData.setHasUnlockEquip(new ArrayList<>());
        }

        List<Integer> hasUnlockEquip = userBaseData.getHasUnlockEquip();
        if (hasUnlockEquip.contains(equipId)) {
            return GameErrorCode.E_HORSE_RUN_HAS_UNLOCK_THIS_EQUIP;
        }
        HorseRunEquipConfig configById = config.getEquipConfigById(equipId);
        if (configById == null) {
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }
        if (userBaseData.getHistoryMaxStage() < configById.getLevel()) {
            return GameErrorCode.E_HORSE_RUN_LEVEL_NO_ENOUGH;
        }
        hasUnlockEquip.add(equipId);
        userBaseData.setUpdateOption();

        HorseRunProto.HorseRunUnlockEventResp.Builder builder = HorseRunProto.HorseRunUnlockEventResp.newBuilder();
        builder.setRet(0);
        builder.addAllHasEquip(hasUnlockEquip);
        player.sendPacket(ClientProtocol.U_HORSE_RUN_UNLOCK_EQUIP,builder);
        return 0;
    }

    /**
     * 切换装备
     */
    public int changeEquip(int activityId,int positionId,int equipId){
        if (positionId <= 0 || positionId >= 4) {
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }


        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        if (equipId != positionId){
            HorseRunConfig config = HorseRunMgr.getConfig();
            HorseRunEquipConfig configById = config.getEquipConfigById(equipId);
            if (configById == null) {
                return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
            }
            if (!userBaseData.getHasUnlockEquip().contains(equipId)) {
                return GameErrorCode.E_HORSE_RUN_NO_UNLOCK_EQUIP;
            }
            if (configById.getPlace() !=positionId) {
                return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
            }
        }

        userBaseData.getEquip().put(positionId, equipId);
        userBaseData.setUpdateOption();

        HorseRunProto.HorseRunChangeEquipResp.Builder builder = HorseRunProto.HorseRunChangeEquipResp.newBuilder();
        builder.setRet(0);
        builder.addAllNewEquip(userBaseData.getEquipList());
        player.sendPacket(ClientProtocol.U_HORSE_RUN_CHANGE_EQUIP,builder);
        uploadHorseDataToCross();
        return 0;
    }

    /**
     * 处理商会马场数据与领取经验请求
     */
    public int getUnionRanchData(int activityId,int needRandomHorse){
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (userBaseData.getHorseAppearance() == 0){
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_CHOOSE_APPEARANCE;
        }

        HorseRunProto.CrossHorseRunGetUnionRanchDataAndExpReq.Builder builder = HorseRunProto.CrossHorseRunGetUnionRanchDataAndExpReq.newBuilder();
        builder.setActivityId(activityId);
        builder.setBriefData(getBriefDataMsg());
        builder.setUserId(getUserId());
        builder.setNeedRandomHorse(needRandomHorse);

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_UNION_RANCH_DATA,builder,activityId);
        return 0;
    }


    /**
     * 处理跨服返回的马场信息和经验
     */
    public HorseRunProto.HorseRunGetUnionRanchDataAndExpResp dealHorseRanchAndAddExpData(HorseRunProto.HorseRunGetUnionRanchDataAndExpResp resp){

        long respAddExp = resp.getAddExp();
        if (respAddExp > 0){
            //活动不在就不处理了
            HorseRunConfig config = HorseRunMgr.getConfig();
            if (config == null) {
                return resp;
            }
            if (checkCanPlayingGame(config.getActivityId()) != 0){
                return resp;
            }

            HorseRunProto.HorseRunHorseLevelUpResult.Builder addExp = addExp(resp.getAddExp(),1);
            if (addExp != null){
                HorseRunProto.HorseRunGetUnionRanchDataAndExpResp.Builder builder = resp.toBuilder();
                builder.setLevelUpResult(addExp);
                builder.setData(getBaseUserDataMsg());
                resp = builder.build();
            }
        }
        return resp;
    }

    /**
     *  获取商会奖牌数据
     */
    public int getUnionMedalData(HorseRunProto.HorseRunGetUnionMedalDataReq req){
        int check = isInShowTime(req.getActivityId());
        if (check != 0) {
            return check;
        }
        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_UNION_MEDAL_DATA,req.toBuilder(),req.getActivityId());
        return 0;
    }

    /**
     * 大吉转盘抽奖
     */
    public int bigLuckyTurnTableDraw(int activityId){
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        if (userBaseData.getTurnTableRemain() <= 0){
            return GameErrorCode.E_HORSE_RUN_TURN_TABLE_TIME_NO_ENOUGH;
        }
        HorseRunConfig config = HorseRunMgr.getConfig();
        int randomValue = WeightHelper.getRandomValue(config.getTurnTableWeightMap());
        HorseRunTurnTableConfig configById = config.getTurnTableConfigById(randomValue);
        if (configById == null){
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }
        HorseRunProto.HorseRunBigLuckyTurnTableDrawResp.Builder builder = HorseRunProto.HorseRunBigLuckyTurnTableDrawResp.newBuilder();

        userBaseData.setTurnTableRemain(userBaseData.getTurnTableRemain()-1);
        if (configById.getType() == 1){
            HorseRunProto.HorseRunHorseLevelUpResult.Builder addExp = addExp(configById.getNum(), 3);
            if (addExp != null){
                builder.setLevelUp(addExp);
            }
        }else if (configById.getType() == 2){
            userBaseData.addExtAttr( eHorseRunAttrEnum.energy.getValue(),configById.getNum());
        }else if (configById.getType() == 3){
            userBaseData.addExtAttr( eHorseRunAttrEnum.artful.getValue(),configById.getNum());
        }else if (configById.getType() == 4){
            userBaseData.addExtAttr( eHorseRunAttrEnum.resistance.getValue(),configById.getNum());
        }
//        else if (configById.getType() == 5){
//            userGamingData.setMaxConfident(userGamingData.getMaxConfident()+configById.getNum());
//            userGamingData.setNowConfident(userGamingData.getNowConfident()+configById.getNum());
//        }
        recalculateActivityAttrAndGrade(false);

        builder.setRet(0);
        builder.setDrawResult(randomValue);
        builder.setData(getBaseUserDataMsg());

        player.sendPacket(ClientProtocol.U_HORSE_RUN_BIG_LUCKY_TURN_TABLE,builder);
        HorseRunLotteryLog lotteryLog = new HorseRunLotteryLog(activityId,getUserId(),configById.getId(),1,userBaseData.getTurnTableRemain(),userBaseData.getActivityGrade());
        AutoLogMgr.add(lotteryLog);
        return 0;
    }

    /**
     * 更新商会成就数据请求
     */
    public void updateUnionCondition(){
        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return;
        }

        if (HorseRunMgr.getConfig() == null) {
            return;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        int userDataCheck = userDataCheck(activityInfo.getActivityId());
        if (userDataCheck != 0) {
            return;
        }
        //不在活动时间不给更新
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }
        //如果玩家都没选过角色 不给玩
        if (userBaseData.getHorseAppearance() == 0){
            return;
        }

        HorseRunProto.CrossUserUpdateUnionConditionReq.Builder builder = HorseRunProto.CrossUserUpdateUnionConditionReq.newBuilder();
        builder.setActivityId(activityInfo.getActivityId());

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_USER_UPDATE_CONDITION_REQ,builder,activityInfo.getActivityId());
    }

    /**
     * 更新商会成就数据返回
     */
    public void updateUnionConditionCrossResp(HorseRunProto.CrossUserUpdateConditionToGame resp ){
        if (resp == null) {
            return;
        }
        if (resp.getRet() != 0){
            log.debug("玩家{} 更新商会成就数据失败,错误码{}",getUserId(),resp.getRet());
            return;
        }

        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return;
        }

        if (HorseRunMgr.getConfig() == null) {
            return;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        int userDataCheck = userDataCheck(activityInfo.getActivityId());
        if (userDataCheck != 0) {
            return;
        }
        //不在活动时间不给更新
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }
        //如果玩家都没选过角色 不给玩
        if (userBaseData.getHorseAppearance() == 0){
            return;
        }

        for (HorseRunProto.CrossUnionScoreData data:resp.getDataList()){
            HorseRunUnionScoreConditionArg arg = new HorseRunUnionScoreConditionArg(data.getRound(),data.getTotalScore());
            player.notifyListener(eGamePlayerEventType.HorseRunUnionScoreAchievement.getValue(),arg);
        }

        if (resp.getTotalGrade()>0){
            player.getModule(ActivityFundModule.class).updateProgress(activityInfo.getActivityId(), resp.getTotalGrade()
            );
        }

    }

    /**
     * 请求轮次赛道信息
     */
    public int getRacingTrackDataReq(HorseRunProto.HorseRunGetRacingTrackReq req){
        int activityId = req.getActivityId();
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();

        //今天是什么天
        int nowDay = DateHelper.calc2DateTDOADays(new Date(activityInfo.getBeginTime() * 1000), new Date());

        if (req.getRound() <= 0 || req.getRound() > nowDay){
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_RACING_TRACK_DATA,req.toBuilder(),activityId);
        return 0;
    }

    /**
     * 小马快跑获取赛马比赛排行榜
     */
    public int getRacingRank(HorseRunProto.HorseRunGetRacingRankDataReq req){

        int activityId = req.getActivityId();
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }
        if (req.getRound() <= 0){
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }
        if (req.getZoneType()<=0||req.getZoneType()>=5){
            return GameErrorCode.E_HORSE_RUN_ARG_ERROR;
        }

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_RACING_RANK_LIST,req.toBuilder(),activityId);

        return 0;
    }

    /**
     * 获取其他小马的数据
     */
    public int getOtherHorseData(HorseRunProto.HorseRunGetOtherHorseDataReq req){
        int activityId = req.getActivityId();
        int check = isInShowTime(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_OTHER_HORSE_DATA,req.toBuilder(),activityId);
        return 0;
    }

    /**
     * 小马报名
     */
    public int signUpHorseRunRacing(HorseRunProto.HorseRunSignUpRacingReq req){
        int activityId = req.getActivityId();
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        HorseRunConfig config = HorseRunMgr.getConfig();
        if (!config.canSign()){
            return GameErrorCode.E_HORSE_RUN_NO_SIGN_TIME;
        }
        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_SIGN_UP_RACING,req.toBuilder(),activityId);
        return 0;
    }

    /**
     * 小马快跑获取未读消息
     */
    public int getUnreadResult(HorseRunProto.HorseRunGetNoReadResultReq req){

        int activityId = req.getActivityId();
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_UNREAD_RESULT,req.toBuilder(),activityId);

        return 0;

    }

    /**
     * 获取商会所有小马数据
     */
    public int getAllUnionHorseData( HorseRunProto.HorseRunGetUnionAllHorseReq req){
        int activityId = req.getActivityId();
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        player.sendUnionActivityGroupPacket(CrossProtocol.C_HORSE_RUN_GET_ALL_UNION_HORSE_DATA,req.toBuilder(),activityId);

        return 0;
    }


    /**
     * 小马快跑跑测
     */
    public String runSkillTest(){
        HorseRunConfig config = HorseRunMgr.getConfig();
        List<List<Integer>> lists = new ArrayList<>();

        String s = "0,2000,2000,2000;0,3167,3167,3167;1,4333,4333,4333;1,5500,5500,5500;1,6667,6667,6667;2,7929,7929,7929;2,9000,9000,9000;2,10167,10167,10167;3,11429,11429,11429;3,12500,12500,12500;3,13667,13667,13667;4,14929,14929,14929;4,16000,16000,16000;4,17263,17263,17263;5,18333,18333,18333;5,19500,19500,19500;5,20763,20763,20763;5,21929,21929,21929;5,23000,23000,23000;6,24263,24263,24263;6,25333,25333,25333;6,26596,26596,26596;6,27667,27667,27667;6,28929,28929,28929;7,30096,30096,30096;7,31167,31167,31167;7,32429,32429,32429;7,33596,33596,33596;7,34763,34763,34763;8,35833,35833,35833;8,37096,37096,37096;8,38263,38263,38263;8,39429,39429,39429;8,40596,40596,40596;9,41763,41763,41763;9,42929,42929,42929;9,44096,44096,44096;9,45359,45359,45359;9,46429,46429,46429;10,47596,47596,47596;10,48859,48859,48859;10,49929,49929,49929;10,51096,51096,51096;10,52359,52359,52359;10,53429,53429,53429;10,54692,54692,54692;10,55763,55763,55763;10,57026,57026,57026;10,58096,58096,58096;10,59359,59359,59359;10,60429,60429,60429;10,61692,61692,61692;10,62859,62859,62859;10,63929,63929,63929;10,65192,65192,65192;10,66359,66359,66359;10,67429,67429,67429;10,68692,68692,68692;10,69859,69859,69859;10,71026,71026,71026;10,72096,72096,72096;10,73455,73455,73455;10,74526,74526,74526;10,75788,75788,75788;10,76859,76859,76859;10,78122,78122,78122;10,79288,79288,79288;10,80359,80359,80359;10,81622,81622,81622;10,82788,82788,82788;10,83859,83859,83859;10,85122,85122,85122;10,86288,86288,86288;10,87455,87455,87455;10,88622,88622,88622;10,89692,89692,89692;10,90955,90955,90955;10,92122,92122,92122;10,93288,93288,93288;10,94551,94551,94551;10,95718,95718,95718;10,96788,96788,96788;10,98051,98051,98051;10,99218,99218,99218;10,100385,100385,100385;10,101551,101551,101551;10,102718,102718,102718;10,103885,103885,103885;10,105051,105051,105051;10,106218,106218,106218;10,107385,107385,107385;10,108551,108551,108551;10,109718,109718,109718;10,110885,110885,110885;10,112147,112147,112147;10,113410,113410,113410;10,114481,114481,114481;10,115647,115647,115647;10,116814,116814,116814;10,117981,117981,117981";
//        String s ="0,2000,2000,2000;0,2500,2500,2500;0,3000,3000,3000;0,3500,3500,3500;1,4000,4000,4000;1,4500,4500,4500;1,5000,5000,5000;1,5500,5500,5500;1,6000,6000,6000;2,6500,6500,6500;2,7000,7000,7000;2,7500,7500,7500;2,8000,8000,8000;2,8500,8500,8500;3,9000,9000,9000;3,9500,9500,9500;3,10000,10000,10000;3,10500,10500,10500;3,11000,11000,11000;4,11500,11500,11500;4,12000,12000,12000;4,12500,12500,12500;4,13000,13000,13000;4,13500,13500,13500;5,14000,14000,14000;5,14500,14500,14500;5,15000,15000,15000;5,15500,15500,15500;5,16000,16000,16000;5,16500,16500,16500;5,17000,17000,17000;5,17500,17500,17500;5,18000,18000,18000;5,18500,18500,18500;6,19000,19000,19000;6,19500,19500,19500;6,20000,20000,20000;6,20500,20500,20500;6,21000,21000,21000;6,21500,21500,21500;6,22000,22000,22000;6,22500,22500,22500;6,23000,23000,23000;6,23500,23500,23500;7,24000,24000,24000;7,24500,24500,24500;7,25000,25000,25000;7,25500,25500,25500;7,26000,26000,26000;7,26500,26500,26500;7,27000,27000,27000;7,27500,27500,27500;7,28000,28000,28000;7,28500,28500,28500;8,29000,29000,29000;8,29500,29500,29500;8,30000,30000,30000;8,30500,30500,30500;8,31000,31000,31000;8,31500,31500,31500;8,32000,32000,32000;8,32500,32500,32500;8,33000,33000,33000;8,33500,33500,33500;9,34000,34000,34000;9,34500,34500,34500;9,35000,35000,35000;9,35500,35500,35500;9,36000,36000,36000;9,36500,36500,36500;9,37000,37000,37000;9,37500,37500,37500;9,38000,38000,38000;9,38500,38500,38500;10,39000,39000,39000;10,39500,39500,39500;10,40000,40000,40000;10,40500,40500,40500;10,41000,41000,41000;10,41500,41500,41500;10,42000,42000,42000;10,42500,42500,42500;10,43000,43000,43000;10,43500,43500,43500;10,44000,44000,44000;10,44500,44500,44500;10,45000,45000,45000;10,45500,45500,45500;10,46000,46000,46000;10,46500,46500,46500;10,47000,47000,47000;10,47500,47500,47500;10,48000,48000,48000;10,48500,48500,48500;10,49000,49000,49000;10,49500,49500,49500;10,50000,50000,50000;10,50500,50500,50500;10,51000,51000,51000;10,51500,51500,51500";
        List<String> strings = StringUtils.stringToStringList(s, ";");
        for (String string:strings){
            List<Integer> integers = StringUtils.stringToIntegerList(string, ",");
            lists.add(integers);
        }

        for (List<Integer> list:lists){
            int people = 1000;
            int refreshTime = 5;
            BigInteger allPeopleTotalAttr = BigInteger.ZERO;

            Map<Integer,Integer> configAttr = new HashMap<>();
            configAttr.put(1,list.get(1));
            configAttr.put(2,list.get(2));
            configAttr.put(3,list.get(3));

            //1000人
            for (int i = 0; i< people ; i++){
                List<Integer> skillList = new ArrayList<>();

                Map<Integer,Integer> baseAttr = new HashMap<>(configAttr);

                //技能数量
                for (int j = 0;j < list.get(0);j++){
                    skillList.add(config.getRandomSkill().getId());
                }
                //算各个属性
                Map<Integer, Integer> totalAttrMap = config.calTotalAttr(baseAttr, skillList);

                //最大总属性
                int maxAttr = totalAttrMap.values().stream().mapToInt(Integer::intValue).sum();
//                System.out.println("ma:第一次随机出");
//                System.out.println("ma:玩家"+i +",属性:"+totalAttrMap+"技能:"+skillList+"属性和"+maxAttr);
//                if(i % 100 == 0){
//                    System.out.println("玩家"+i +",属性:"+totalAttrMap+"技能:"+skillList+"属性和"+maxAttr);
//                }

                for (int index = 0;index < skillList.size();index++){
                    for (int z=0;z < refreshTime;z++){
                        List<Integer> tempSkill = new ArrayList<>(skillList);
                        //随机一个新的
                        int randomId = config.getRandomSkill().getId();
//                        System.out.println("ma:第"+z+"次随机,随机第"+index+"个技能");
//                        System.out.println("ma:随机出技能"+randomId);
                        tempSkill.set(index, randomId);
                        //算各个属性
                        Map<Integer, Integer> tempTotalAttr = HorseRunMgr.calTotalAttr(baseAttr, tempSkill);
                        //最大总属性
                        int tempMaxAttr = tempTotalAttr.values().stream().mapToInt(Integer::intValue).sum();

//                        System.out.println("ma:玩家"+i +"基础属性"+ baseAttr+",属性:"+tempTotalAttr+"技能:"+tempSkill+"属性和"+tempMaxAttr);
                        if (tempMaxAttr > maxAttr){
                            maxAttr = tempMaxAttr;
                            skillList.set(index,randomId);
                            totalAttrMap = tempTotalAttr;
//                            System.out.println("ma:属性替换 玩家"+i +"基础属性"+ baseAttr+",属性:"+totalAttrMap+"技能:"+skillList+"属性和"+maxAttr);
                        }

                    }
                }
                allPeopleTotalAttr = allPeopleTotalAttr.add(BigInteger.valueOf(maxAttr));

//                System.out.println("ma:玩家最后的"+i +",属性:"+totalAttrMap+"技能:"+skillList+"属性和"+maxAttr);

            }
            System.out.println("ma:小马测试 技能孔位初始为"+configAttr+"平均的属性和为"+allPeopleTotalAttr.divide(BigInteger.valueOf(people))+"刷新次数"+refreshTime);

        }



        return "";
    }

    /**
     * 洗点
     */
    public int refreshAttrPoint(int activityId){
        int check = checkCanPlayingGame(activityId);
        if (check != 0) {
            return check;
        }

        int userDataCheck = userDataCheck(activityId);
        if (userDataCheck != 0) {
            return userDataCheck;
        }

        HorseRunConfig config = HorseRunMgr.getConfig();
        int refreshAttrPointItem = config.getRefreshAttrPointItem();
        if (refreshAttrPointItem <= 0) {
            log.error("小马快跑洗点道具配置错误,activityId:{}",activityId);
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }

        int refreshAttrTime = userBaseData.getRefreshAttrTime();
        int refreshAttrCostNum = config.getRefreshAttrCostNum(refreshAttrTime);
        if (refreshAttrCostNum <= 0) {
            log.error("小马快跑洗点道具配置错误,activityId:{}",activityId);
            return GameErrorCode.E_HORSE_RUN_CONFIG_ERROR;
        }
        boolean canReset = false;
        for (int level:userBaseData.getPointAttrLevel().values()){
            if (level>0){
                canReset = true;
            }
        }
        if (!canReset) {
            return GameErrorCode.E_HORSE_RUN_NO_NEED_RESET_ATTR;
        }

        //拿消耗
        Property cost = new Property(refreshAttrPointItem, refreshAttrCostNum);
        if (!player.getModule(CurrencyModule.class).removeCurrency(cost,eLogMoneyType.HorseRun,eLogMoneyType.HorseRunRefreshAttrCost)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        HorseRunProto.HorseRunResetAttrSkillResp.Builder builder = HorseRunProto.HorseRunResetAttrSkillResp.newBuilder();
        builder.setRet(0);
        //次数+1
        userBaseData.setRefreshAttrTime(refreshAttrTime + 1);
        //获取一下空属性
        Map<Integer, Integer> initAttrLevelMap = HorseRunMgr.getInitAttrLevelMap();
        //先设置初始属性map
        userBaseData.setPointAttrLevel(initAttrLevelMap);
        //技能点不会不正常产出 每个等级给的一点
        userBaseData.setAttrPoint(userBaseData.getHorseLevel()-1);
        //刷新积分
        recalculateActivityAttrAndGrade(true);
        userBaseData.setUpdateOption();
        builder.setData(getBaseUserDataMsg());

        player.sendPacket(ClientProtocol.U_HORSE_RUN_RESET_ATTR_SKILL,builder);
        return 0;
    }

    /**
     * 7.4新增 付费增加皮肤
     */
    public void addPaySkin(int horseSkin){
        HorseRunConfig config = HorseRunMgr.getConfig();
        if (config == null){
            log.error("小马快跑添加皮肤失败,活动数据不存在,userId{},skinId{}",getUserId(),horseSkin);
            return;
        }

        int userDataCheck = userDataCheck(config.getActivityId());
        if (userDataCheck != 0) {
            log.error("小马快跑添加皮肤失败,玩家数据不存在,userId{},activityId{},skinId{}",getUserId(),config.getActivityId(),horseSkin);
            return;
        }

        List<Integer> hasUnlockEquip = userBaseData.getHasUnlockEquip();
        if (hasUnlockEquip.contains(horseSkin)){
            log.error("小马快跑添加皮肤失败,已经获得过皮肤,userId{},activityId{},skinId{}",getUserId(),config.getActivityId(),horseSkin);
            return;
        }

        hasUnlockEquip.add(horseSkin);
        userBaseData.setUpdateOption();
        return;

    }
    /**
     * 判断小马在活动展示期
     */
    public int isInShowTime(int activityId){
        //如果系统没开启
        if (!SystemOpenMgr.systemOpen(player, eSystemId.HorseRun.getValue())) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_UNLOCK;
        }

        if (HorseRunMgr.getConfig() == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        ActivityInfo activityInfo = HorseRunMgr.getConfig().getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        //不在展示期间
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_NO_EXIST;
        }
        if (activityInfo.getActivityId() != activityId){
            return GameErrorCode.E_HORSE_RUN_ACTIVITY_ID_ERROR;
        }

        return 0;
    }




}
